package com.baijiayun.live.ui.speakerlist.item;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import android.os.Bundle;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.baijiayun.live.ui.R;
import com.baijiayun.live.ui.activity.LiveRoomRouterListener;
import com.baijiayun.live.ui.scanner.QRcodeDialog;
import com.baijiayun.live.ui.utils.QueryPlus;
import com.baijiayun.livecore.context.LPConstants;
import com.baijiayun.livecore.context.LiveRoom;
import com.baijiayun.livecore.models.imodels.IUserModel;
import com.baijiayun.livecore.utils.LPRxUtils;
import com.baijiayun.livecore.wrapper.LPRecorder;
import com.baijiayun.livecore.wrapper.impl.LPCameraView;
import com.baijiayun.liveuibase.utils.ThemeDataUtil;
import com.baijiayun.liveuibase.widgets.dialog.ThemeMaterialDialogBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;

/**
 * Created by Shubo on 2019-07-25.
 */
public class LocalItem extends BaseSwitchItem implements Playable, LifecycleObserver {

    private QueryPlus $;
    protected Activity context;
    protected LiveRoom liveRoom;
    private ViewGroup rootView;
    protected LPRecorder recorder;
    protected LPCameraView cameraView;
    protected ViewGroup container;
    protected FrameLayout videoContainer;
    protected boolean shouldStreamVideo;
    protected TextView speakerName;
    private boolean isZOrderMediaOverlay = false;
    //是否处于后台状态
    protected boolean isInBackgroundStatus = false;
    protected Dialog dialog;
    protected Dialog scannerDialog;
    protected QRcodeDialog qrCodeDialog;
    protected SpeakItemType itemType;
    protected String qrCodeUrl;
    private Disposable disposableOfQRCode;
    protected boolean enableLocalCamera;
    protected boolean forceKeepAlive = false;

    public LocalItem(ViewGroup rootView, LiveRoomRouterListener routerListener) {
        super(routerListener);
        this.rootView = rootView;
        this.context = (Activity) rootView.getContext();
        liveRoom = routerListener.getLiveRoom();
        recorder = liveRoom.getRecorder();
        status = SwitchableStatus.SpeakList;
        itemType = liveRoom.getCurrentUser().getUserId().equals(liveRoom.getSpeakQueueVM().getPresenter()) ? SpeakItemType.Presenter : SpeakItemType.Record;
        initView();
    }

    protected void initView() {
        container = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.bjy_item_view_speaker_local, rootView, false);
        $ = QueryPlus.with(container);
        videoContainer = (FrameLayout) $.id(R.id.item_local_speaker_avatar_container).view();
        speakerName = (TextView) $.id(R.id.item_local_speaker_name).view();
        refreshNameTable();
        registerClickEvent($.contentView());
    }

    public void refreshItemType() {
        itemType = liveRoom.getCurrentUser().getUserId().equals(liveRoom.getSpeakQueueVM().getPresenter()) ? SpeakItemType.Presenter : SpeakItemType.Record;
        if (itemType != SpeakItemType.Presenter && !TextUtils.isEmpty(qrCodeUrl)) {
            qrCodeUrl = "";
        }
    }

    @SuppressLint("SetTextI18n")
    public void refreshNameTable() {
        IUserModel currentUser = liveRoom.getCurrentUser();
        if (currentUser.getType() == LPConstants.LPUserType.Teacher) {
            String teacherLabel = liveRoom.getCustomizeTeacherLabel();
            teacherLabel = TextUtils.isEmpty(teacherLabel) ? context.getString(R.string.live_teacher_hint) : "(" + teacherLabel + ")";
            speakerName.setText(liveRoom.getCurrentUser().getName() + teacherLabel);
        } else if (currentUser.getType() == LPConstants.LPUserType.Assistant) {
            String assistantLabel = liveRoom.getCustomizeAssistantLabel();
            assistantLabel = TextUtils.isEmpty(assistantLabel) ? "(助教)" : "(" + assistantLabel + ")";
            if (liveRoom.getPresenterUser() != null && liveRoom.getPresenterUser().getUserId().equals(currentUser.getUserId())) {
                assistantLabel = "(主讲)";
            }
            speakerName.setText(liveRoom.getCurrentUser().getName() + assistantLabel);
        } else {
            speakerName.setText(liveRoom.getCurrentUser().getName());
        }
    }

    protected boolean attachVideoOnResume, attachAudioOnResume;

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
        isInBackgroundStatus = false;
        if (attachAudioOnResume) {
            streamAudio();
            attachAudioOnResume = false;
        }
        LPRxUtils.dispose(disposableOfMediaRemoteControl);
        if (liveRoom != null && liveRoom.getSpeakQueueVM().isReplacedUser()) {
            return;
        }
        if (attachVideoOnResume) {
            streamVideo();
            attachVideoOnResume = false;
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onStop() {
        if (context.isFinishing()) {
            return;
        }
        isInBackgroundStatus = true;
        // 屏幕分享中不停止推流
        if (recorder.isScreenSharing()) {
            return;
        }
        attachAudioOnResume = isAudioStreaming();
        attachVideoOnResume = isVideoStreaming();
        if (liveRoom != null && liveRoom.getSpeakQueueVM().isReplacedUser()) {
            if (recorder != null) {
                recorder.detachAudio();
            }
        } else {
            stopStreaming();
        }
        subscribeBackgroundMediaRemoteControl();
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy() {
        onRemove();
    }

    public void onRemove() {
        LPRxUtils.dispose(disposableOfMediaRemoteControl);
        LPRxUtils.dispose(disposableOfQRCode);
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
        }
        if (scannerDialog != null && scannerDialog.isShowing()) {
            scannerDialog.dismiss();
        }
        if (qrCodeDialog != null && qrCodeDialog.isAdded()) {
            qrCodeDialog.dismissAllowingStateLoss();
        }
    }

    @Override
    public void showOptionDialog() {
        List<String> options = new ArrayList<>();
        if (isInFullScreen()) {
            options.add(getString(R.string.live_full_screen_exit));
        } else {
            //坐席区为了兼容iOS，暂时不加全屏选项
            if (getSwitchableType() != SwitchableType.SpeakItem) {
                options.add(getString(R.string.live_full_screen));
            }
        }
        //全屏和最大化时没有放大窗口选项
        if (canSwitchPPTAndMainVideo() && !isInFullScreen() && status !=  SwitchableStatus.MaxScreen) {
            options.add(getString(R.string.live_max_screen));
        }
        if (liveRoom.getPartnerConfig().isEnableSwitchPresenter == 1 && !liveRoom.getSpeakQueueVM().isPresenterUser(liveRoom.getCurrentUser()) && liveRoom.isTeacher()) {
            options.add(getString(R.string.live_set_to_presenter));
        }
        //外接设备配置项
        if (liveRoom.getSpeakQueueVM().enableAttachPhoneCamera()) {
            if (getSwitchableType() == SwitchableType.MainItem && !liveRoom.getSpeakQueueVM().hasAsCameraUser()) {
                options.add(getString(R.string.base_live_scanner_camera_start));
            }
            if (liveRoom.getSpeakQueueVM().isReplacedUser()) {
                options.add(getString(R.string.base_live_scanner_camera_end));
            }
        }

        if(liveRoom.isUseWebRTC() && liveRoom.getPartnerConfig().enableSwitchMirrorMode && liveRoom.isTeacherOrAssistant()) {
            options.add(getString(R.string.bjy_live_horizon_mirror));
            options.add(getString(R.string.bjy_live_vertical_mirror));
        }
        if (liveRoom.isClassStarted()) {
            if (recorder.isVideoAttached()) {
                options.add(getString(R.string.live_close_video));
            } else {
                addOpenVideoOpts(options);
            }
        }
        if (context.isFinishing()) return;
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
        }
        dialog = new ThemeMaterialDialogBuilder(context)
                .items(options)
                .itemsCallback((materialDialog, view, i, charSequence) -> {
                    if (context.isFinishing() || context.isDestroyed()) return;
                    if (getString(R.string.live_close_video).equals(charSequence.toString())) {
                        routerListener.detachLocalVideo();
                    } else if (getString(R.string.live_open_video).equals(charSequence.toString())) {
                        routerListener.attachLocalVideo();
                    } else if (getString(R.string.live_max_screen).equals(charSequence.toString())) {
                        if (!canSwitchPPTAndMainVideo()) {
                            return;
                        }
                        switchPPTVideoSync();
                    } else if (getString(R.string.live_set_to_presenter).equals(charSequence.toString())) {
                        liveRoom.getSpeakQueueVM().requestSwitchPresenter(liveRoom.getCurrentUser().getUserId());
                    } else if (getString(R.string.live_recorder_switch_camera).equals(charSequence.toString())) {
                        recorder.switchCamera();
                    } else if (getString(R.string.live_full_screen).equals(charSequence.toString())) {
                        switchToFullScreen(true);
                    } else if (getString(R.string.live_full_screen_exit).equals(charSequence.toString())) {
                        switchToFullScreen(false);
                    } else if (getString(R.string.base_live_scanner_camera_start).equals(charSequence.toString())) {
                        startScannerCamera();
                    } else if (getString(R.string.base_live_scanner_camera_end).equals(charSequence.toString())) {
                        endScannerCamera();
                    } else if(getString(R.string.bjy_live_horizon_mirror).equals(charSequence.toString())) {
                        boolean horizonMirror = liveRoom.getSpeakQueueVM().getHorizontalMirrorModeSet().contains(liveRoom.getCurrentUser().getNumber());
                        boolean verticalMirror = liveRoom.getSpeakQueueVM().getVerticalMirrorModeSet().contains(liveRoom.getCurrentUser().getNumber());
                        liveRoom.getSpeakQueueVM().requestMirrorModeSwitch(liveRoom.getCurrentUser().getNumber(), liveRoom.getCurrentUser().getUserId(), !horizonMirror, verticalMirror);
                    } else if(getString(R.string.bjy_live_vertical_mirror).equals(charSequence.toString())) {
                        boolean horizonMirror = liveRoom.getSpeakQueueVM().getHorizontalMirrorModeSet().contains(liveRoom.getCurrentUser().getNumber());
                        boolean verticalMirror = liveRoom.getSpeakQueueVM().getVerticalMirrorModeSet().contains(liveRoom.getCurrentUser().getNumber());
                        liveRoom.getSpeakQueueVM().requestMirrorModeSwitch(liveRoom.getCurrentUser().getNumber(), liveRoom.getCurrentUser().getUserId(), horizonMirror, !verticalMirror);
                    }
                    materialDialog.dismiss();
                })
                .show();
    }
    //扫码视频直播
    public void startScannerCamera() {
        if (TextUtils.isEmpty(qrCodeUrl)) {
            disposableOfQRCode = liveRoom.getSpeakQueueVM().getObservableOfAsCameraUrl(0)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(s -> {
                        qrCodeUrl = s;
                        showQRcodeDialog(s);
                    },throwable -> {});
        } else {
            showQRcodeDialog(qrCodeUrl);
        }
    }
    public void endScannerCamera() {
        scannerDialog = new ThemeMaterialDialogBuilder(context)
                .title(R.string.base_live_scanner_ext_camera_end_tip)
                .positiveText(R.string.base_live_confirm)
                .negativeText(R.string.base_live_cancel)
                .widgetColor(ThemeDataUtil.getColorFromThemeConfigByAttrId(context, R.attr.base_theme_live_product_color))
                .positiveColor(ThemeDataUtil.getColorFromThemeConfigByAttrId(context, R.attr.base_theme_live_product_color))
                .negativeColor(ContextCompat.getColor(context,R.color.base_warning_color))
                .onPositive((dialog, which) -> {
                    enableLocalCamera = dialog.isPromptCheckBoxChecked();
                    liveRoom.getSpeakQueueVM().stopAsCameraUser();
                    qrCodeUrl = "";
                    dialog.dismiss();
                })
                .checkBoxPromptRes(R.string.base_live_open_main_camera, false, null)
                .show();
    }

    private void showQRcodeDialog(String qrCodeUrl) {
        qrCodeDialog = new QRcodeDialog();
        Bundle bundle = new Bundle();
        String url = TextUtils.isEmpty(qrCodeUrl) ? "http:www.baijiayun.com" : qrCodeUrl;
        bundle.putString("url",url);
        qrCodeDialog.setArguments(bundle);
        if (context instanceof AppCompatActivity) {
            AppCompatActivity activity = (AppCompatActivity) context;
            qrCodeDialog.show(activity.getSupportFragmentManager(),QRcodeDialog.class.getSimpleName());
        }
    }

    protected void addOpenVideoOpts(List<String> options) {
        // do nothing
    }

    private String getString(@StringRes int resId) {
        return context.getString(resId);
    }

    @Override
    public boolean hasVideo() {
        return shouldStreamVideo;
    }

    @Override
    public boolean hasAudio() {
        return recorder != null && recorder.isAudioAttached();
    }

    public void setShouldStreamVideo(boolean shouldStreamVideo) {
        this.shouldStreamVideo = shouldStreamVideo;
    }

    public void setZOrderMediaOverlay(boolean ZOrderMediaOverlay) {
        isZOrderMediaOverlay = ZOrderMediaOverlay;
    }

    @Override
    public boolean isVideoStreaming() {
        return recorder.isVideoAttached();
    }

    @Override
    public boolean isAudioStreaming() {
        return recorder.isAudioAttached();
    }

    @Override
    public boolean isStreaming() {
        return recorder.isPublishing();
    }

    protected void streamAudio() {
        if (!recorder.isPublishing()) {
            recorder.publish();
        }
        recorder.attachAudio();
    }

    private void streamVideoInternal() {
        if (cameraView == null) {
            cameraView = new LPCameraView(context);
        }
        showVideoOpen();
        cameraView.setZOrderMediaOverlay(isZOrderMediaOverlay);
        recorder.setPreview(cameraView);
        if (!recorder.isPublishing()) {
            recorder.publish();
        }
    }

    protected void streamVideo() {
        streamVideoInternal();
        recorder.attachVideo();
    }

    protected void showVideoOpen() {
        // do nothing
    }

    /**
     * 关闭视频之后显示
     */
    protected void showVideoClose() {
        // do nothing
    }

    /**
     * 同时打开音视频
     */
    protected void streamAVideo() {
        streamVideoInternal();
        recorder.attachAVideo();
    }

    @Override
    public void stopStreaming() {
        showVideoClose();
        videoContainer.removeAllViews();
        recorder.stopPublishing();
    }

    @Override
    public void refreshPlayable() {
        if (!shouldStreamVideo && !hasAudio()) {
            stopStreaming();
        } else {
            //attention app处于后台状态不再允许操作视频推流（本来就已经停止推流了，处于后台开关摄像头不生效)，后台操作需在onResume之后恢复
            if (!isInBackgroundStatus) {
                if (shouldStreamVideo) {
                    streamVideo();
                } else {
                    recorder.detachVideo();
                    showVideoClose();
                }
            }
        }
    }

    @Override
    public void refreshPlayable(boolean videoOn, boolean audioOn) {
        if (videoOn && audioOn) {
            streamAVideo();
        } else if (!videoOn && !audioOn) {
            stopStreaming();
        } else {
            if (!isInBackgroundStatus) {
                if (videoOn) {
                    streamVideo();
                } else {
                    recorder.detachVideo();
                    showVideoClose();
                }
            }
            if (audioOn) {
                streamAudio();
            } else {
                recorder.detachAudio();
            }
        }
    }

    @Override
    public void switchToSpeakList() {
        super.switchToSpeakList();
        if (cameraView != null) {
            cameraView.setZOrderMediaOverlay(true);
        }
        invalidVideo();
        hideNickName(false);
    }

    @Override
    public void switchToMainScreen() {
        super.switchToMainScreen();
        if (cameraView != null) {
            cameraView.setZOrderMediaOverlay(true);
        }
        invalidVideo();
        hideNickName(false);
    }

    @Override
    public void switchToMaxScreen() {
        super.switchToMaxScreen();
        if (cameraView != null) {
            cameraView.setZOrderMediaOverlay(false);
        }
        invalidVideo();
        hideNickName(true);
    }

    @Override
    public void switchToFullScreen(boolean isFullScreen) {
        super.switchToFullScreen(isFullScreen);
        if (cameraView != null) {
            cameraView.setZOrderMediaOverlay(true);
        }
        invalidVideo();
        if (isFullScreen) {
            hideNickName(true);
        }
    }


    protected void hideNickName(boolean hide) {
        // do nothing
    }

    /**
     * 大班课item默认都是speakItem
     *
     * @return
     */
    @Override
    public SwitchableType getSwitchableType() {
        return SwitchableType.SpeakItem;
    }

    public void invalidVideo() {
        recorder.invalidVideo();
    }

    @Override
    public IUserModel getUser() {
        return liveRoom.getCurrentUser();
    }

    @Override
    public void notifyAwardChange(int count) {
        if (count > 0) {
            $.id(R.id.item_local_speaker_award_count_tv).visibility(View.VISIBLE);
            $.id(R.id.item_local_speaker_award_count_tv).text(String.valueOf(count));
        }
    }

    @Override
    public String getIdentity() {
        return liveRoom.getCurrentUser().getUserId();
    }

    @Override
    public SpeakItemType getItemType() {
        return itemType;
    }

    public boolean isForceKeepAlive() {
        return forceKeepAlive || liveRoom.getRoomType() == LPConstants.LPRoomType.OneOnOne;
    }

    public void setForceKeepAlive(boolean forceKeepAlive) {
        this.forceKeepAlive = forceKeepAlive;
    }

    @Override
    public View getView() {
        return container;
    }

    protected Disposable disposableOfMediaRemoteControl;

    /**
     * 退到后台监听remote_media_control
     */
    protected void subscribeBackgroundMediaRemoteControl() {
        if (liveRoom.getRecorder() == null) {
            //兼容竖屏模板问题(竖屏模板没有监听kickOut解绑生命周期)
            return;
        }
        disposableOfMediaRemoteControl = liveRoom.getSpeakQueueVM()
                .getObservableOfMediaControl()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(iMediaControlModel -> {
                    attachVideoOnResume = iMediaControlModel.isVideoOn();
                    attachAudioOnResume = iMediaControlModel.isAudioOn();
                });
    }
}
